function Map(/*Game*/ game, /*String*/ map){
	this.game = game;
	this.map = null;
	this.solidMap = null;
	this.player = null;
	this.view = null;
	this.offset = vec2(0,0);
	this.brush = vec2(0,0);
	this.graph = null;
	this.instances = [];
	this.orderIns = [];
	this.message = null;
	
	if (map == "test"){
		this.map = this.getDummyMap();
		this.solidMap = this.parseSolidMap(this.map);
		this.player = new Player(game.sprites.male1, vec2(2, 2), this);
		this.instances.push(this.player);
		this.orderIns.push(this.player);
		player = this.player;
		
		this.view = vec2(Math.ceil(game.view.b / config.gridSizeY), Math.ceil(game.view.a / config.gridSizeX));
		
		this.createInstances();
		this.graph = new Graph(this.solidMap);
	}
}
var player;

Map.prototype.findPath = function(/*vec2*/ start, /*vec2*/ end){
	start = this.graph.nodes[start.b][start.a];
	end = this.graph.nodes[end.b][end.a];
	
	var path = astar.search(this.graph.nodes, start, end, {diagonal: true});
	if (path.length == 0) return [];
	
	var ret = [];
	for (var i=0,len=path.length;i<len;i++){
		ret.push(vec2(path[i].y, path[i].x));
	}
	
	return ret;
};

Map.prototype.parseSolidMap = function(map){
	var solid = [];
	for (var y=0,ylen=map.length;y<ylen;y++){
		solid[y] = [];
		for (var x=0,xlen=map[y].length;x<xlen;x++){
			var t = map[y][x];
			s = (Tiles[t].solid)? 0 : 1;
			
			solid[y][x] = s;
		}
	}
	
	return solid;
};

Map.prototype.createInstances = function(){
	var tree = new SimpleInstance(vec2(2, 5), this.game.sprites.trees, this);
	tree.subImg = vec2(0,0); this.solidMap[5][2] = 0;
	this.instances.push(tree); this.orderIns.push(tree);
	
	var text = this.game.splitText("I hope you enjoy testing the options of this engine. You can enter the houses by clicking in the door while been nearby", '16px "Arial"', 368);
	text.push("", "Click this box to close it");
	var sign = new SimpleInstance(vec2(5, 1), this.game.sprites.misc, this);
	sign.subImg = vec2(1,0); this.solidMap[1][5] = 0;
	sign.message = {title: "Welcome to this demo v1.0", message: text};
	this.instances.push(sign); this.orderIns.push(sign);
};

Map.prototype.getDummyMap = function(){
	var map = [
		[59,49,52,57,49,61,68,49,58,66,49],
		[49, 2, 2, 2, 2, 2, 2, 2, 2, 2,50],
		[60, 2, 2, 2, 2, 2, 2, 2, 2, 2,55],
		[53, 2, 2, 3, 3, 3, 3, 3, 2, 2,53],
		[62, 2, 2, 3, 3, 3, 3, 3, 2, 2,57],
		[49, 2, 2, 3, 3, 3, 3, 3, 2, 2,52],
		[52, 2, 2, 3, 3, 3, 3, 3, 2, 2,59],
		[51, 2, 2, 3, 3, 3, 3, 3, 2, 2,64],
		[57, 2, 2, 2, 2, 2, 2, 2, 2, 2,68],
		[53, 2, 2, 2, 2, 2, 2, 2, 2, 2,49],
		[67,49,52,55,60,53,49,55,68,61,50],
	];
	
	return map;
};

Map.prototype.setOffset = function(){
	var x = this.game.view.a / 2 - this.game.sprites.grass.imgW / 2;
	var y = this.game.view.b / 2 - this.game.sprites.grass.imgH / 2;
	
	var playerP = this.player.position;
	var xx = playerP.a - playerP.b;
	var yy = playerP.b + playerP.a;
	
	x -= xx * config.gridSizeX; 
	y -= yy * config.gridSizeY;
	
	this.offset = vec2(x, y);
	//this.offset = vec2(0, 0);
};

Map.prototype.drawMessage = function(){
	if (this.message == null) return;
	
	var ctx = this.game.eng.ctx;
	var size = this.message.message.length * 20 + 70;
	var x1 = ctx.width / 2 - 200;
	var y1 = ctx.height / 2 - size / 2;
	
	ctx.fillStyle = "rgb(220,220,220)";
	ctx.fillRect(x1,y1,400,size);
	ctx.strokeStyle = "rgb(0,0,0)";
	ctx.lineWidth = 3;
	ctx.strokeRect(x1,y1,400,size);
	
	ctx.fillStyle = "rgb(255,255,255)";
	ctx.fillRect(x1 + 16,y1 + 16,368,32);
	
	ctx.fillStyle = "rgb(0,0,0)";
	ctx.font = '24px "Arial"';
	ctx.textAlign = "left";
	
	ctx.fillText(this.message.title, x1 + 20, y1 + 40);
	
	ctx.font = '16px "Arial"';
	for (var i=0,len=this.message.message.length;i<len;i++){
		ctx.fillText(this.message.message[i], x1 + 20, y1 + 72 + (16 * i));
	}
	
	var mp = this.game.mouseP;
	if (mp.a > x1 && mp.a < x1 + 400 && mp.b > y1 && mp.b < y1 + size){
		document.body.style.cursor = "pointer";
		if (this.game.getMousePressed()){
			this.message = null;
		}
	}
};

Map.prototype.drawName = function(x, y, name){
	var ctx = this.game.eng.ctx;
	
	var measure = ctx.measureText(name);
	
	ctx.fillStyle = "rgba(255,255,255,0.5)";
	ctx.fillRect(x - measure.width / 2 - 8, y - 30, measure.width + 16, 30);
	ctx.strokeStyle = "rgb(255,255,255)";
	ctx.lineWidth = 3;
	ctx.strokeRect(x - measure.width / 2 - 8, y - 30, measure.width + 16, 30);
	
	ctx.fillStyle = "rgb(0,0,0)";
	ctx.font = '24px "Arial"';
	ctx.textAlign = "center";
	ctx.fillText(name, x, y - 8);
};

Map.prototype.drawBrush = function(){
	return;
	var eng = this.game.eng;
	var ctx = eng.ctx;
	
	var spr = this.game.sprites.brushes;
	var x = this.game.mouseP.a;
	var y = this.game.mouseP.b;
	
	var tx = Math.floor(x / 92 + y / 55);
	var ty = Math.floor(y / 55 - x / 92);
	
	x = tx * 48 - ty * 48 + this.offset.a + 16;
	y = tx * 23 + ty * 23 + this.offset.b + 28;
	
	var mouseP = vec2(x, y);
	
	ctx.save();
	ctx.globalAlpha = 0.5;
	eng.drawSprite(spr, this.brush, mouseP);
	ctx.restore();
};

Map.prototype.draw = function(){
	var eng = this.game.eng;
	
	var playerP = this.player.position;
	var xi = Math.floor(playerP.a) - this.view.a;
	var yi = Math.floor(playerP.b) - this.view.b;
	var xlen = xi + this.view.a * 2;
	var ylen = yi + this.view.b * 2;
	if (xi < 0) xi = 0; if (xlen >= this.map[0].length) xlen = this.map[0].length;
	if (yi < 0) yi = 0; if (ylen >= this.map.length) ylen = this.map.length;
	
	for (var y=yi;y<ylen;y++){
		var yOff = vec2(-y * config.gridSizeX, y * config.gridSizeY);
		for (var x=xi;x<xlen;x++){
			var t = this.map[y][x];
			var tile = Tiles[t];
			var offset = vec2(0, 0);
			if (tile.offset) offset = tile.offset;
			
			var img = this.game.sprites[tile.sprite];
			eng.drawSprite(img, tile.position, vec2(x * config.gridSizeX + yOff.a + this.offset.a + offset.a, x * config.gridSizeY + yOff.b + this.offset.b + offset.b));
		}
	}
};

Map.prototype.loop = function(){
	this.draw();
	
	var ins = [];
	for (var i=0,len=this.orderIns.length;i<len;i++){
		var inst = this.orderIns[i];
		inst.loop();
		
		//Rearange the instances acoording to the position
		var add = false;
		for (var j=0,jlen=ins.length;j<jlen;j++){
			if (inst.position.a < ins[j].position.a || inst.position.b < ins[j].position.b){
				ins.splice(j, 0, inst);
				j = jlen;
				add = true;
			}
		}
		
		if (!add){ ins.push(this.orderIns[i]); }
	}
	this.orderIns = ins;
	
	this.player.draw(true); //Redraw the player (in semitransparence) for overlaying the objects
	
	this.drawBrush();
	this.drawMessage();
};
